﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Globalization;
using System.Linq;
using System.Text;
using System.IO;

namespace AlbumCreator
{
    public class Worker
    {

        private string _outputPath;
        private string _inputPath;
        private const int ThumbWidth = 200;
        private const int ImageWidth = 1200;


        public string OutputPath
        {
            get { return _outputPath; }
            set { _outputPath = value; }
        }

        public string InputPath
        {
            get { return _inputPath; }
            set { _inputPath = value; }
        }


        public void CreateAlbumFromFolder()
        {
            //This is the initial function call at the root of the folder structure.
            CreateAlbumFromFolder("");
        }


        //Recursive method looping through the foldertree, creating html's + resized images for thumbs and images.
        public void CreateAlbumFromFolder(string folderSubPath)
        {
            string htmlOutput = "";
            string inPath = _inputPath + @"\" + folderSubPath + @"\";
            string outPath = _outputPath + @"\" + folderSubPath + @"\";

            if (folderSubPath != "" & !Directory.Exists(outPath))
                Directory.CreateDirectory(outPath);

            string[] subDirectories = Directory.GetDirectories(inPath);
            string[] files = Directory.GetFiles(inPath);

            //Load Html template
            var myFile = new StreamReader(@"..\..\Template.htm");
            string htmlTemplate = myFile.ReadToEnd();


            //Loop through the folders
            foreach (string subDirectory in subDirectories)
            {
                //Recursive loop through all folders
                string subDirectoryName = new DirectoryInfo(subDirectory).Name;
                Console.WriteLine(subDirectoryName);

                if (folderSubPath == "")
                    CreateAlbumFromFolder(subDirectoryName);
                else
                    CreateAlbumFromFolder(folderSubPath + @"\" + subDirectoryName);

                htmlOutput += "<a href='" + subDirectoryName + "/index.htm'>" + subDirectoryName + "</a>\r\n";
            }
            htmlTemplate = htmlTemplate.Replace("<insertfolders />", htmlOutput);
            htmlOutput = "";

            //Loop through the files
            foreach (string file in files)
            {
                string imageName = Path.GetFileName(file);
                if (imageName.ToUpper().EndsWith(".JPG"))
                {
                    try
                    {
                        CreateThumb(inPath, outPath, imageName);
                        htmlOutput += "<a href='" +
                            ImageWidth.ToString(CultureInfo.InvariantCulture) + @"/" + imageName + "'><img src='" +
                            ThumbWidth.ToString(CultureInfo.InvariantCulture) + @"/" + imageName + "'></a>\r\n";
                    }
                    catch (Exception exception)
                    {

                        Console.WriteLine(exception);
                    }
                }
            }

            //write html file
            File.WriteAllText(outPath + "\\index.htm", htmlTemplate.Replace("<insertimages />", htmlOutput));

        }




        private void CreateThumb(string inPath, string outPath, string imageFileName)
        {
            Directory.CreateDirectory(outPath + ThumbWidth.ToString(CultureInfo.InvariantCulture));
            ResizeImage(inPath + imageFileName, outPath + ThumbWidth.ToString(CultureInfo.InvariantCulture) + @"\" + imageFileName, ThumbWidth, 200, 60L);
            Directory.CreateDirectory(outPath + ImageWidth.ToString(CultureInfo.InvariantCulture));
            ResizeImage(inPath + imageFileName, outPath + ImageWidth.ToString(CultureInfo.InvariantCulture) + @"\" + imageFileName, ImageWidth, 1200, 25L);
        }






        private void ResizeImage(string originalFile, string newFile, int newWidth, int maxHeight, long quality)
        {
            //skip if fileresize already exists, this wil speedup the creation process after images have been added to the source.
            if (!File.Exists(newFile))
            {
                System.Drawing.Image fullsizeImage = System.Drawing.Image.FromFile(originalFile);


                if (fullsizeImage.Width <= newWidth)
                {
                    newWidth = fullsizeImage.Width;
                }

                int newHeight = fullsizeImage.Height * newWidth / fullsizeImage.Width;
                if (newHeight > maxHeight)
                {
                    // Resize with height instead
                    newWidth = fullsizeImage.Width * maxHeight / fullsizeImage.Height;
                    newHeight = maxHeight;
                }

                Bitmap b = new Bitmap(newWidth, newHeight);
                Graphics g = Graphics.FromImage((Image)b);
                g.InterpolationMode = InterpolationMode.Bicubic;
                g.CompositingQuality = CompositingQuality.HighSpeed;
                g.DrawImage(fullsizeImage, 0, 0, newWidth, newHeight);
                g.Dispose();                // Clear handle to original file so that we can overwrite it if necessary
                fullsizeImage.Dispose();

                //Get the image encoder
                ImageCodecInfo jgpEncoder = GetEncoder(ImageFormat.Jpeg);
                System.Drawing.Imaging.Encoder myEncoder = System.Drawing.Imaging.Encoder.Quality;

                //set the quality parameter
                EncoderParameters myEncoderParameters = new EncoderParameters(1);
                EncoderParameter myEncoderParameter = new EncoderParameter(myEncoder, quality);
                myEncoderParameters.Param[0] = myEncoderParameter;

                // Save resized picture
                b.Save(newFile, jgpEncoder, myEncoderParameters);
            }
        }


        private ImageCodecInfo GetEncoder(ImageFormat format)
        {
            ImageCodecInfo[] codecs = ImageCodecInfo.GetImageDecoders();
            foreach (ImageCodecInfo codec in codecs)
            {
                if (codec.FormatID == format.Guid)
                {
                    return codec;
                }
            }
            return null;
        }

    }
}
